// 本模块要求的基础权限在index.js中定义为crm模块权限，即用户roles中具有crm-xxx，具体到每一个API接口所需要的权限，则应该在每个函数中去考查，例如某个用户是否可以查看某条记录
const express = require("express");
const eae = require("express-async-errors");
const router = express.Router();

const moment = require("moment");
const tutils = require("../tutils");
const rds = require("../rds");
const task = require("../task");
const logger = require("../logger");
const axios = require("axios");
const fs = require("fs");
const uuid = require("uuid");
const Dysmsapi20170525 = require('@alicloud/dysmsapi20170525');
const OpenApi = require('@alicloud/openapi-client');
const Util = require('@alicloud/tea-util');

// 创建阿里云短信客户端
const createSmsClient = () => {
    let config = new OpenApi.Config({
        //图腾生命科学
        accessKeyId: process.env['TTSMKX_ALIYUN_ACCESS_KEY_ID'],
        accessKeySecret: process.env['TTSMKX_ALIYUN_ACCESS_KEY_SECRET'],
        // 图腾生命医学
        //accessKeyId: process.env['TTSMYX_ALIYUN_ACCESS_KEY_ID'],
        //accessKeySecret: process.env['TTSMYX_ALIYUN_ACCESS_KEY_SECRET'],
    });
    config.endpoint = `dysmsapi.aliyuncs.com`;
    return new Dysmsapi20170525.default(config);
};

// 复用发送短信的核心逻辑
async function sendSms(phone, templateCode, templateParam) {
    const client = createSmsClient();
    const sendSmsRequest = new Dysmsapi20170525.SendSmsRequest({
        phoneNumbers: phone,
        signName: "图腾生命", // 签名需与短信服务配置一致
        templateCode: templateCode,
        templateParam: JSON.stringify(templateParam)
    });

    const runtime = new Util.RuntimeOptions({});
    return await client.sendSmsWithOptions(sendSmsRequest, runtime);
}

router.post("/send-verify-code", async (req, res) => {
    const { phone, code } = req.body;
    if (!phone || !code) {
        return res.json({ errcode: 1, errmsg: "手机号和验证码不能为空" });
    }
    const templateCode = "SMS_206655517";
    const templateParam = { code: code };
    const result = await sendSms(phone, templateCode, templateParam);
    if (result.body.code === "OK") {
        return res.json({ errcode: 0, errmsg: "验证码发送成功" });
    } else {
        return res.json({ errcode: 1, errmsg: result.body.message });
    }
});

// 支持 GET 的验证码路由（生产环境不推荐！）
router.get("/send-verify-code", async (req, res) => {
    const { phone, code } = req.query;
    if (!phone || !code) {
        return res.json({ errcode: 1, errmsg: "手机号和验证码不能为空" });
    }
    const templateCode = "SMS_206655517";
    const templateParam = { code: code };
    const result = await sendSms(phone, templateCode, templateParam);
    if (result.body.code === "OK") {
        return res.json({ errcode: 0, errmsg: "验证码发送成功" });
    } else {
        return res.json({ errcode: 1, errmsg: result.body.message });
    }
});

// 统一处理 GET 和 POST 请求
async function handleSendSms(req, res) {
    const params = req.method === 'POST' ? req.body : req.query;
    const { phone, templateCode, templateParam: paramStr } = params;
    // 校验必填参数
    if (!phone || !templateCode) {
        return res.json({ errcode: 1, errmsg: "手机号和模板代码不能为空" });
    }
    // 处理模板参数（GET 需解析 JSON 字符串）
    let templateParam;
    if (paramStr) {
        try {
            templateParam = req.method === 'POST' ? paramStr : JSON.parse(paramStr);
        } catch (e) {
            return res.json({ errcode: 1, errmsg: "参数 templateParam 格式错误" });
        }
    }
    // 调用短信服务
    const client = createSmsClient();
    const sendSmsRequest = new Dysmsapi20170525.SendSmsRequest({
        phoneNumbers: phone,
        signName: "广州图腾生命科学",
        templateCode: templateCode,
        templateParam: templateParam ? JSON.stringify(templateParam) : undefined,
    });
    const runtime = new Util.RuntimeOptions({});
    const result = await client.sendSmsWithOptions(sendSmsRequest, runtime);
    console.log('send-sms result', result);
    // 返回结果
    if (result.body.code === "OK") {
        return res.json({ errcode: 0, errmsg: "发送成功" });
    } else {
        return res.json({ errcode: 1, errmsg: result.body.message });
    }
}

// 同时支持 GET 和 POST, GET比较不安全，但可以简单尝试
router.get("/send-sms", handleSendSms);
router.post("/send-sms", handleSendSms);
// GET 请求示例, 其中 templateParam=%7B%22code%22%3A%221234%22%7D 是 {"code":"1234"} 的 URL 编码
// send-sms?phone=13812345678&templateCode=SMS_123&templateParam=%7B%22code%22%3A%221234%22%7D

function formatWaybillToText(data) {
    let text = "";
    const waybillInfo = data.waybill_info;

    // 格式化waybill_info为文本
    text += "【运单信息】\n";
    text += `运单ID: ${waybillInfo.waybill_id}\n`;
    (text += "运单状态:"), waybillInfo.status, "\n";
    if (waybillInfo.path) {
        text += "【路由轨迹】\n";
        waybillInfo.path.path_action.forEach((action) => {
            text += `${new Date(action.action_time * 1000).toLocaleString()}: ${action.action_msg} \n`;
        });
    }
    text += "\n";

    const deliveryInfo = data.delivery_info;
    if (deliveryInfo) {
        // 格式化delivery_info为文本
        text += "【配送信息】\n";
        text += `配送商ID: ${deliveryInfo.delivery_id}`;
        text += `配送商名: ${deliveryInfo.delivery_name}`;
    }
    text += "\n";

    const shopInfo = data.shop_info;
    // 格式化shop_info为文本
    if (shopInfo) {
        text += "【店铺信息】\n";
        shopInfo.goods_info.detail_list.forEach((item) => {
            text += `商品名称: ${item.goods_name}`;
            if (item.goods_img_url) {
                text += `商品图片: ${item.goods_img_url}`;
            }
            text += "\n";
        });
    }
    return text;
}

router.get("/update-waybill", async (req, res) => {
    const order_id = req.query.order_id || 0;
    const ret = await tutils.updateOrderWaybill(order_id);
    const text = ret.errcode == 0 ? formatWaybillToText(ret) : ret.errmsg;
    return res.send(`<pre style="white-space: pre-line;">${text}</pre>`);
});

router.get("/update-waybills", async (req, res) => {
    const code = req.query.code || "";
    let cond = "";
    let time;
    switch (code) {
        case "":
        case "15d":
            cond = ` and pay_time >= ${moment().subtract(15, "days").unix()}`;
            break;
        case "5d":
            cond = ` and pay_time >= ${moment().subtract(5, "days").unix()}`;
            break;
        case "all":
            // do nothing, cond is already ''
            break;
        default:
            // handle other cases
            break;
    }

    const ret = tutils.updateWaybills(cond);
    return res.json({ errcode: 0, errmsg: ` ${code} ok` });
});

router.get("/show-tmall-tracks", async (req, res) => {
    const uid = req.query.uid || 0;
    const [rows] = await rds.query(
        `select concat('[', DATE_FORMAT(FROM_UNIXTIME(add_time), '%Y-%m-%d %H:%i:%s'), '] ', route, ' options: ', options) as track from tutem_mall.eb_user_click where uid = ${uid} order by id desc`
    );
    let responseText = `Tmall tracks for U#${uid}\n`;
    responseText += rows.map((row) => row.track).join("\n"); // 将每条记录转换成字符串并用换行符连接起来
    res.type("text/plain"); // 设置响应类型为纯文本
    res.send(responseText); // 发送纯文本响应
    //return res.json(rows);
});

router.get("/show-torder-infos", async (req, res) => {
    const uid = req.query.uid || 0;
    const [rows] = await rds.query(
        `select concat('[', DATE_FORMAT(FROM_UNIXTIME(pay_time), '%Y-%m-%d %H:%i:%s'), '] ', real_name, ' phone: ', user_phone, ' addr:', user_address) as track from tutem_mall.eb_store_order where uid = ${uid} and paid = 1 order by id desc`
    );
    let responseText = `Torder tracks for U#${uid}\n`;
    responseText += rows.map((row) => row.track).join("\n"); // 将每条记录转换成字符串并用换行符连接起来
    res.type("text/plain"); // 设置响应类型为纯文本
    res.send(responseText); // 发送纯文本响应
    //return res.json(rows);
});

// 保存 URL 到文件的函数
const saveUrlToFile = async (url, fn) => {
    try {
        const response = await axios({
            method: "GET",
            url: url,
            responseType: "stream",
        });

        const writer = fs.createWriteStream(fn);
        response.data.pipe(writer);

        return new Promise((resolve, reject) => {
            writer.on("finish", resolve);
            writer.on("error", reject);
        }).then(() => 200); // 成功状态码
    } catch (e) {
        const errCode = parseInt(e.message.split(" ")[0] || "839");
        return errCode;
    }
};

// 下载远程文件到本地服务器，并返回本地服务器的访问链接地址
const saveUrlToNamedFile = (url) => {
    const missing = "missing.png";
    const shortUrl = url.split("?sign=")[0];
    const words = shortUrl.split(".");
    const suffix = words[words.length - 1];
    const uuidValue = uuid.v4();
    const named = new Date().toISOString().split("T")[0]; // YYYY-MM-DD
    const fn = `${named}-${uuidValue}.${suffix}`;
    const fp = `/home/www/tutem_mall/public/uploads/survey/${fn}`;

    return saveUrlToFile(url, fp)
        .then((statusCode) => {
            return statusCode === 200
                ? `https://mall.totemlife.cn/uploads/survey/${fn}`
                : `https://mall.totemlife.cn/uploads/survey/${missing}`;
        })
        .catch(() => {
            return `https://mall.totemlife.cn/uploads/survey/${missing}`;
        });
};

// 根据问题ID获取答案的函数
const getAnswerByQid = async (questions, id) => {
    if (!questions || !Array.isArray(questions)) {
        return "";
    }
    for (const answer of questions) {
        // 允许模糊匹配，将 id 转换为字符串进行比较
        if (answer.id.includes(id.toString())) {
            switch (answer.type) {
                case "datetime":
                case "text":
                case "textarea":
                    // 对于日期时间、文本或文本区域类型，返回文本
                    return answer.text;
                case "radio":
                    // 对于单选类型，返回第一个选项的文本
                    return answer.options[0] ? answer.options[0].text : "";
                case "checkbox":
                case "select":
                    // 对于复选框或下拉选择类型，拼接所有选项的文本
                    return answer.options.reduce((text, opt, optIdx) => {
                        return optIdx > 0 ? `${text} ${opt.text}` : opt.text;
                    }, "");
                case "upload":
                case "signature":
                    const filePromises = answer.files.map((file) =>
                        saveUrlToNamedFile(file.url)
                    );
                    result = (await Promise.all(filePromises)).join("\n");
                    return result;
                default:
                    // 其他类型，返回答案的字符串表示
                    return answer.toString();
            }
        }
    }
    // 如果没有找到匹配的答案，返回空字符串
    return "";
};

// 解析问卷数据的函数
const parseSurveyPayload = async (survey, payload) => {
    let { questions } = payload.answer[0];
    let maps = {};
    if (survey == "14784502")
        maps = {
            "q-19-lHop": {
                name: "channel",
                prefix: "【了解渠道】",
                suffix: "\n",
            },
            "q-47-ukAc": {
                name: "stores",
                prefix: "【购买途径】",
                suffix: "\n",
            },
            "q-23-YFj9": { name: "user", prefix: "【实际用户】", suffix: "\n" },
            "q-24-9lYj": {
                name: "gendar",
                prefix: "【用户性别】",
                suffix: "\n",
            },
            "q-43-YXTV": {
                name: "group",
                prefix: "【用户年龄】",
                suffix: "\n",
            },
            "q-33-rfgu": {
                name: "purposes",
                prefix: "【针对疾病】",
                suffix: "\n",
            },
            "q-44-9rzJ": {
                name: "history",
                prefix: "【疾病时间】",
                suffix: "\n",
            },
            "q-26-RiSx": {
                name: "diagnosis",
                prefix: "【疾病诊断】",
                suffix: "\n",
            },
            "q-34-J6UL": {
                name: "therapy",
                prefix: "【治疗方案】",
                suffix: "\n",
            },
            "q-21-A9V7": {
                name: "goods",
                prefix: "【所用产品】",
                suffix: "\n",
            },
            "q-28-Q7RD": { name: "time", prefix: "【使用时长】", suffix: "\n" },
            "q-45-QO5Q": {
                name: "serve",
                prefix: "【日均用量】",
                suffix: "\n",
            },
            "q-36-MSbM": {
                name: "symptoms",
                prefix: "【症状变化】",
                suffix: "\n",
            },
            "q-37-GpTn": {
                name: "metrics",
                prefix: "【指标变化】",
                suffix: "\n",
            },
            "q-38-NLsl": {
                name: "proof",
                prefix: "【检测单据】",
                suffix: "\n",
            },
            "q-39-kAfq": {
                name: "rating",
                prefix: "【总体评价】",
                suffix: "\n",
            },
            "q-41-aVpx": {
                name: "reason",
                prefix: "【评价原因】",
                suffix: "\n",
            },
            "q-42-rCbX": {
                name: "question",
                prefix: "【问题留言】",
                suffix: "\n",
            },
            "q-46-gLt7": {
                name: "shareFurther",
                prefix: "【可做访谈】",
                suffix: "\n",
            },
            "q-40-U2HY": {
                name: "signature",
                prefix: "【授权签名】",
                suffix: "\n",
            },
        };
    let text = "";
    const answers = {};

    const processMapEntry = async (key) => {
        const value = await getAnswerByQid(questions, key);
        const { name, prefix, suffix } = maps[key];
        text += `${prefix}${value}${suffix}`;
        answers[name] = value;
    };

    // 等待所有条目的处理完成
    await Promise.all(Object.keys(maps).map(processMapEntry));

    let uid = 0;
    questions = payload.answer?.[1]?.questions;
    if (questions) {
        const argText = await getAnswerByQid(questions, "custom-arg-01");
        uid = parseInt(argText);
    }
    return { answers, text, uid };
};

// 腾讯问卷 Webhook 路由
router.post("/survey-webhook", async (req, res) => {
    const { id, action, created_at, payload } = req.body;
    const surveyId = String(payload.survey_id);
    const answerId = String(payload.answer_id);
    const {
        answers = {},
        text = "",
        uid = 0,
    } = await parseSurveyPayload(surveyId, payload);

    const answerLink = `https://wj.qq.com/survey_detail.html?sid=${surveyId}&aid=${answerId}&user_type=editor`;
    const payloadString = JSON.stringify(payload);
    const now = Math.floor(Date.now() / 1000); // MySQL 时间戳
    const sql = `INSERT INTO tutem_mall.eb_tupal_survey (uid, action, survey_id, payload, answers, answers_json, add_time) VALUES (?, ?, ?, ?, ?, ?, ?)`;
    const [rows] = await rds.query(sql, [
        uid,
        action,
        surveyId,
        payloadString,
        text,
        JSON.stringify(answers),
        now,
    ]);

    if (uid > 0 && surveyId == "14784502") {
        const link_id = `SURVEY-${surveyId}`;
        const title = `2024H1用户随访问卷`;
        const points = 1999;
        const mark = `完成2024H1用户随访获得奖励`;
        const result = await tutils.grantPoints(
            uid,
            link_id,
            title,
            points,
            mark
        ); //因为有link_id，所以可以保证不会重复提交

        let act =
            action === "answer.create"
            ? "提交了"
            : action === "answer.update"
            ? "更新了"
            : action === "answer.delete"
            ? "删除了"
            : "搞了搞";
        let msg = `U#${uid}${act}${title}\n ${text} \n`;
        if (result.errcode === 0) msg += ` ${points}健康金豆已发放`;

        await task.notifyWework(1, msg, 1000026); //ENG
        await task.notifyXiaoteng(199999, msg);
    }

    // 发送提醒（这里需要根据实际的提醒服务进行调整）
    res.status(200).json({});
});

module.exports = router;
